package com.qdlc.p2p.biz.service.impl;

import java.text.MessageFormat;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.qd.p2p.sina.pay.enums.AccountType;
import com.qd.p2p.sina.pay.enums.IdentityType;
import com.qd.p2p.sina.pay.enums.PayType;
import com.qd.p2p.sina.pay.param.CreateHostingCollectTradeParam;
import com.qd.p2p.sina.pay.param.DepositExtendParam;
import com.qd.p2p.sina.pay.response.CreateHostingCollectTradeResponse;
import com.qd.p2p.sina.service.SinaPayService;
import com.qdlc.p2p.biz.service.TppTradeService;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.biz.tpp.model.SinaCollectTrade;
import com.qdlc.p2p.biz.tpp.model.SinaPayTrade;
import com.qdlc.p2p.biz.util.NotifyRequestUrl;
import com.qdlc.p2p.common.constant.SinaConstant;
import com.qdlc.p2p.common.constant.Summary;
import com.qdlc.p2p.common.constant.TradeCode;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.dao.TppDao;
import com.qdlc.p2p.dal.dao.TppTradeLogDao;
import com.qdlc.p2p.dal.dto.Tpp;
import com.qdlc.p2p.dal.dto.TppTradeLog;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.model.TppTradeLogModel;
import com.qdlc.p2p.dal.util.UserUtils;

/**
 * 第三方 代收/代付 交易
 *
 * @author yy
 * @version 1.0
 * @date
 */
@Service("tppTradeService")
public class TppTradeServiceImpl implements TppTradeService {

    private static final Logger logger = Logger.getLogger(TppTenderLogServiceImpl.class);

    @Resource
    private TppTradeLogDao tppTradeLogDao;

    @Resource
    private TppDao tppDao;

    @Autowired
    private SinaPayService sinaPayService;

    @Override
    public void save(TppTradeLog tppTradeLog) {
        tppTradeLogDao.save(tppTradeLog);
    }

    @Override
    public void update(TppTradeLog tppTradeLog) {
        tppTradeLogDao.update(tppTradeLog);
        tppTradeLogDao.flush();
    }

    @Override
    public TppTradeLog find(String orderNo) {
        return tppTradeLogDao.find(orderNo);
    }

    @Override
    public SinaCollectTrade collTrade(TppTradeLog tppTradeLog) {
        return collTrade(tppTradeLog, "");
    }

    @Override
    public SinaCollectTrade collTrade(TppTradeLog tppTradeLog, String summary) {
        tppTradeLog.setAddTime(DateUtil.getNow());
        tppTradeLogDao.save(tppTradeLog);
        String serviceType = tppTradeLog.getServiceType();
        User user = UserUtils.getUserByTppCustId(tppTradeLog.getTppUserCustId());
        User toUser = UserUtils.getUserByTppCustId(tppTradeLog.getToTppUserCustId());
        Tpp tpp = new Tpp(TppTradeLogModel.getTppServiceType(serviceType), serviceType, user, toUser, tppTradeLog.getMoney(), null, tppTradeLog.getOrderNo(), tppTradeLog.getBorrowId() + "");
        if (tppTradeLog.getIdentityType() == SinaConstant.IDENTITY_TYPE_EMAIL) {
            tpp.setTppUserCustId(tppTradeLog.getTppUserCustId());
        }
        TppModel tppModel = TppModel.instance(tpp);
        tppModel.setOut_trade_code(tppTradeLog.getTradeType());

        String newSummary = summary;
        if (StringUtil.isEmpty(newSummary)) {
            newSummary = Summary.getSummaryNameByType(serviceType);
        }
        tppModel.setSummary(newSummary);

        tppModel.setCan_repay_on_failed(SinaConstant.SINA_YES);
        tppModel.setIdentityType(tppTradeLog.getIdentityType());
        TppBaseInterface tppService = TppServiceFactory.newIntance();
        SinaCollectTrade collTrade = null;
        try {
            collTrade = (SinaCollectTrade) tppService.tppCollectTrade(tppModel);
            tppModel.setStatus(TppModel.STATUS_SUCEESS);
            tppModel.setRespDesc("代收处理成功");
        } catch (Exception e) {
            tppModel.setStatus(TppModel.STATUS_FAIL);
            tppModel.setRespDesc(e.getMessage());
            e.printStackTrace();
        } finally {
            if (!SinaConstant.TRADE_SERVICE_AUTO_TENDER.equals(serviceType) &&
                    !SinaConstant.TRADE_SERVICE_TENDER.equals(serviceType)) {
                tppDao.save(tppModel.prototype());
            }
        }
        return collTrade;
    }

    /**
     * 代收
     *
     * @param tppTradeLog
     * @param summary
     * @author linya 2016-01-12
     */
    @Override
    public void collTrade(TppTradeLog tppTradeLog, Summary summary, String notifyUrl) {
        logger.info(MessageFormat.format("++++[准备代收][{0}]代收单号{1},用户{2}代收资金{3}元给用户{4}！", summary.getSummaryName(), tppTradeLog.getOrderNo(), tppTradeLog.getTppUserCustId(), tppTradeLog.getMoney(), tppTradeLog.getToTppUserCustId()));

        if (notifyUrl == null) {
            notifyUrl = NotifyRequestUrl.COLLECT_TRADE_NOTIFY_URL;
        }

        //托管账户
        User user = UserUtils.getUserByTppCustId(tppTradeLog.getTppUserCustId());
        //收款账户
        User toUser = UserUtils.getUserByTppCustId(tppTradeLog.getToTppUserCustId());
        //交易类型
        String serviceType = tppTradeLog.getServiceType();
        //保存代收/代付交易记录
        tppTradeLogDao.save(tppTradeLog);

        //第三方处理记录
        Tpp tpp = new Tpp(TppTradeLogModel.getTppServiceType(serviceType), serviceType, user, toUser, tppTradeLog.getMoney(), null, tppTradeLog.getOrderNo(), tppTradeLog.getBorrowId() + "");
        if (tppTradeLog.getIdentityType() == SinaConstant.IDENTITY_TYPE_EMAIL) {
            tpp.setTppUserCustId(tppTradeLog.getTppUserCustId());
        }
        TppModel tppModel = TppModel.instance(tpp);
        tppModel.setOut_trade_code(tppTradeLog.getTradeType());
        tppModel.setSummary(Summary.getSummaryNameByType(serviceType));
        tppModel.setCan_repay_on_failed(SinaConstant.SINA_YES);
        tppModel.setIdentityType(tppTradeLog.getIdentityType());
        //调用代收接口
        CreateHostingCollectTradeParam param = new CreateHostingCollectTradeParam();
        param.setOutTradeNo(tppModel.getOrderId())
                .setOutTradeCode(TradeCode.C1001)
                .setPayerId(tppModel.getTppUserCustId())
                .setGoodsId(tppModel.getTppBorrowId())
                .setPayerIdentityType(IdentityType.EMAIL)
                .setAmount(tppModel.getMoney())
                .setSummary(tppModel.getSummary())
                .setCanRepayOnFailed(tppModel.getCan_repay_on_failed())
                .setNotifyUrl(notifyUrl);
        DepositExtendParam extend = new DepositExtendParam();
        extend.setPayType(PayType.balance);
        extend.setAccountType(AccountType.BASIC);
        param.setPayParam(extend);
        CreateHostingCollectTradeResponse response = sinaPayService.createHostingCollectTrade(param);
        logger.info(MessageFormat.format("++++[新浪代收]代收单号{0},代收请求{1}!", response.getOutTradeNo(), response.success() ? "成功" : "失败"));
        if (response.success()) {
            tppModel.setStatus(TppModel.STATUS_SUCEESS);
            tppModel.setRespDesc("代收处理成功");
        } else {
            tppModel.setStatus(TppModel.STATUS_FAIL);
            tppModel.setRespDesc(response.getResponseMessage());
        }
        if (Summary.TENDER.getSummaryType().equals(serviceType)
                || Summary.AUTO_TENDER.getSummaryType().equals(serviceType)) {
            // do nothing!
        } else {
            tppDao.save(tppModel.prototype());
        }
    }

    @Override
    public List<TppTradeLog> find(long borrowRepaymentId, String serviceType, String tradeType) {
        return tppTradeLogDao.find(borrowRepaymentId, serviceType, tradeType);
    }

    @Override
    public SinaPayTrade payTrade(TppTradeLog tppTradeLog) {
        if (SinaConstant.TRADE_SERVICE_RED_ENVELOPE_EXCHAGE.equals(tppTradeLog.getServiceType())) {
            return redPayTrade(tppTradeLog);
        } else {
            return null;
        }
    }

    /**
     * 红包兑换 代付方法
     *
     * @param tppTradeLog
     * @param
     * @return
     */
    private SinaPayTrade redPayTrade(TppTradeLog tppTradeLog) {

        String serviceType = tppTradeLog.getServiceType();
        User user = UserUtils.getUserByTppCustId(tppTradeLog.getTppUserCustId());
        User toUser = UserUtils.getUserByTppCustId(tppTradeLog.getToTppUserCustId());
        Tpp tpp = new Tpp(TppTradeLogModel.getTppServiceType(serviceType), serviceType, user, toUser, tppTradeLog.getMoney(), null);
        TppModel tppModel = TppModel.instance(tpp);
        tppModel.setOut_trade_code(tppTradeLog.getTradeType());
        tppModel.setSummary(Summary.getSummaryNameByType(serviceType));
        TppBaseInterface tppService = TppServiceFactory.newIntance();
        SinaPayTrade payTrade = null;
        try {
            payTrade = (SinaPayTrade) tppService.tppPayTrade(tppModel);
            if (payTrade == null) {
                tpp.setStatus(TppModel.STATUS_FAIL);
                tpp.setRespDesc("代付处理失败");
            } else {
                tpp.setStatus(TppModel.STATUS_SUCEESS);
                tpp.setRespDesc("代付处理成功");
            }
        } catch (Exception e) {
            // TODO 基本不可能执行到
            tpp.setStatus(TppModel.STATUS_FAIL);
            tpp.setRespDesc("代付处理失败");
            e.printStackTrace();
        } finally {
            tppModel.setStatus(tpp.getStatus());
            tppModel.setRespDesc(tpp.getRespDesc());
            tppDao.save(tppModel.prototype());
        }

        // 生成收红包的Log
        TppTradeLog newTppTradeLog = new TppTradeLog();
        newTppTradeLog.setTppUserCustId(tppTradeLog.getToTppUserCustId());
        newTppTradeLog.setToTppUserCustId(null);
        newTppTradeLog.setIdentityType(SinaConstant.IDENTITY_TYPE_UID); // 红包收款不可能是平台，所以用UID
        newTppTradeLog.setMoney(tppTradeLog.getMoney());
        newTppTradeLog.setOrderNo(tppModel.getOrderId());
        newTppTradeLog.setTradeStatus(SinaConstant.TRADE_STATUS_PAY_FINISHED);
        newTppTradeLog.setTradeType(tppTradeLog.getTradeType());
        newTppTradeLog.setServiceType(tppTradeLog.getServiceType());
        newTppTradeLog.setBorrowId(0);
        newTppTradeLog.setBorrowRepaymentId(0);
        newTppTradeLog.setSplitList(null);
        newTppTradeLog.setMemo("红包兑换现金");
        newTppTradeLog.setTradeTime(DateUtil.getNow());
        newTppTradeLog.setAddTime(DateUtil.getNow());
        tppTradeLogDao.save(newTppTradeLog);
        return payTrade;
    }

    /**
     * 更新订单状态
     */
    @Override
    public void updateTradeLog(TppTradeLog tppTradeLog, String depositStatus, String remark) {
        System.out.println(MessageFormat.format(" id = {0} orderId = {1} depositStatus = {2} ", tppTradeLog.getId(), tppTradeLog.getOrderNo(), depositStatus));
        // 保证已经是最终态 则 不再更新状态
        if (!SinaConstant.TRADE_STATUS_FINISHED.equals(tppTradeLog.getTradeStatus()) && !SinaConstant.TRADE_STATUS_FAILED.equals(tppTradeLog.getTradeStatus())) {
            tppTradeLog.setTradeStatus(depositStatus); // 回调状态
            if (StringUtil.isNotEmpty(remark)) {
                tppTradeLog.setRemark(remark);
            }
            //System.out.println(MessageFormat.format("11111111111111 id = {0} orderId = {1} depositStatus = {2} ", tppTradeLog.getId(), tppTradeLog.getOrderNo(), depositStatus));
        }
        if (StringUtil.isNotEmpty(depositStatus)) {
            // 新浪状态保存 以免多次执行
            if (StringUtil.isEmpty(tppTradeLog.getSinaStatus())) {
                tppTradeLog.setSinaStatus(depositStatus);
                //System.out.println(MessageFormat.format("2222222222222 id = {0} orderId = {1} depositStatus = {2} ", tppTradeLog.getId(), tppTradeLog.getOrderNo(), depositStatus));
            } else {
                tppTradeLog.setSinaStatus(tppTradeLog.getSinaStatus() + " " + depositStatus);
                //System.out.println(MessageFormat.format("33333333333 id = {0} orderId = {1} depositStatus = {2} ", tppTradeLog.getId(), tppTradeLog.getOrderNo(), depositStatus));
            }
        }
        update(tppTradeLog);
    }
}
